import { Node, Edge } from '@xyflow/react';

interface N8nNode {
  id: string;
  name: string;
  type: string;
  position: [number, number];
  parameters?: any;
  credentials?: any;
  typeVersion?: number;
  webhookId?: string;
  alwaysOutputData?: boolean;
}

interface N8nWorkflow {
  meta?: any;
  nodes: N8nNode[];
  connections: Record<string, { main: Array<Array<{ node: string; type: string; index: number }>> }>;
}

export function importN8nWorkflow(n8nData: N8nWorkflow): { nodes: Node[]; edges: Edge[] } {
  const nodes: Node[] = [];
  const edges: Edge[] = [];

  // Convert n8n nodes to ReactFlow nodes
  n8nData.nodes.forEach((n8nNode) => {
    let nodeType = 'action'; // default
    let nodeCategory = 'action';
    
    // Determine node type based on n8n node type
    if (n8nNode.type.includes('Trigger') || n8nNode.type.includes('trigger')) {
      nodeType = 'trigger';
      nodeCategory = 'trigger';
    } else if (n8nNode.type.includes('if') || n8nNode.type.includes('switch')) {
      nodeType = 'condition';
      nodeCategory = 'condition';
    }

    // Extract meaningful label from name and type
    let label = n8nNode.name;
    let subtitle = '';
    let icon = 'default';

    // Map common n8n node types to our icons
    if (n8nNode.type.includes('github')) {
      icon = 'github';
      subtitle = 'GitHub Integration';
    } else if (n8nNode.type.includes('http')) {
      icon = 'webhook';
      subtitle = 'HTTP Request';
    } else if (n8nNode.type.includes('pipedrive')) {
      icon = 'database';
      subtitle = 'Pipedrive CRM';
    } else if (n8nNode.type.includes('mail')) {
      icon = 'mail';
      subtitle = 'Email Service';
    } else if (n8nNode.type.includes('if')) {
      icon = 'filter';
      subtitle = 'Conditional Logic';
    } else if (n8nNode.type.includes('noOp')) {
      icon = 'code2';
      subtitle = 'No Operation';
    }

    const reactFlowNode: Node = {
      id: n8nNode.id,
      type: nodeType,
      position: {
        x: n8nNode.position[0],
        y: n8nNode.position[1]
      },
      data: {
        label,
        subtitle,
        icon,
        n8nType: n8nNode.type,
        parameters: n8nNode.parameters,
        credentials: n8nNode.credentials
      }
    };

    nodes.push(reactFlowNode);
  });

  // Convert n8n connections to ReactFlow edges
  Object.entries(n8nData.connections).forEach(([sourceNodeName, connections]) => {
    const sourceNode = n8nData.nodes.find(node => node.name === sourceNodeName);
    if (!sourceNode) return;

    connections.main.forEach((outputConnections, outputIndex) => {
      outputConnections.forEach((connection, connectionIndex) => {
        const targetNode = n8nData.nodes.find(node => node.name === connection.node);
        if (!targetNode) return;

        // Handle multiple outputs (like for condition nodes)
        let sourceHandle = undefined;
        if (outputConnections.length > 1 || outputIndex > 0) {
          sourceHandle = outputIndex === 0 ? 'true' : 'false';
        }

        const edge: Edge = {
          id: `${sourceNode.id}-${targetNode.id}-${outputIndex}-${connectionIndex}`,
          source: sourceNode.id,
          target: targetNode.id,
          sourceHandle,
          animated: true,
          style: { stroke: 'hsl(var(--workflow-connection))' }
        };

        edges.push(edge);
      });
    });
  });

  return { nodes, edges };
}

// Helper function to export current workflow to n8n format
export function exportToN8nFormat(nodes: Node[], edges: Edge[]): N8nWorkflow {
  const n8nNodes: N8nNode[] = nodes.map(node => ({
    id: node.id,
    name: String(node.data.label || 'Untitled'),
    type: String(node.data.n8nType || `n8n-nodes-base.${node.type}`),
    position: [node.position.x, node.position.y],
    parameters: node.data.parameters || {},
    ...(node.data.credentials && { credentials: node.data.credentials }),
    typeVersion: 1
  }));

  const connections: Record<string, { main: Array<Array<{ node: string; type: string; index: number }>> }> = {};

  // Group edges by source node
  const edgesBySource = edges.reduce((acc, edge) => {
    if (!acc[edge.source]) acc[edge.source] = [];
    acc[edge.source].push(edge);
    return acc;
  }, {} as Record<string, Edge[]>);

  Object.entries(edgesBySource).forEach(([sourceId, sourceEdges]) => {
    const sourceNode = nodes.find(n => n.id === sourceId);
    if (!sourceNode) return;

    const sourceNodeName = String(sourceNode.data.label || 'Untitled');
    connections[sourceNodeName] = { main: [] };

    // Group by source handle (for condition nodes with multiple outputs)
    const edgesByHandle = sourceEdges.reduce((acc, edge) => {
      const handle = edge.sourceHandle || '0';
      if (!acc[handle]) acc[handle] = [];
      acc[handle].push(edge);
      return acc;
    }, {} as Record<string, Edge[]>);

    Object.keys(edgesByHandle).sort().forEach(handle => {
      const handleEdges = edgesByHandle[handle];
      const connectionArray = handleEdges.map(edge => {
        const targetNode = nodes.find(n => n.id === edge.target);
        return {
          node: String(targetNode?.data.label || 'Untitled'),
          type: 'main',
          index: 0
        };
      });
      connections[sourceNodeName].main.push(connectionArray);
    });
  });

  return {
    meta: {
      instanceId: 'imported-workflow-' + Date.now()
    },
    nodes: n8nNodes,
    connections
  };
}